//
//  LBFacListView.m
//  app
//
//  Created by luckyRoy on 2017/5/4.
//  Copyright © 2017年 NAICAI LI. All rights reserved.
//

#import "LBFacListView.h"
#import <Masonry/Masonry.h>
#import "LBFacAllHeader.h"

typedef NS_ENUM(NSInteger, LBFacListViewType) {
    LBFacListViewTypeTableView = 1,
    LBFacListViewTypeCollectionView = 2 
};

static NSString  * const LBReuseHeaderSectionIdentifier = @"LBReuseHeaderSectionIdentifier";

@interface LBFacListView ()<UICollectionViewDelegate,UICollectionViewDataSource,UITableViewDelegate,UITableViewDataSource,UICollectionViewDelegateFlowLayout>

@property (assign, nonatomic) LBFacListViewType viewType;

@property (copy, nonatomic) LBFacListViewCellClick cellClick;

@property (copy, nonatomic) LBFacListViewOtherClick otherClick;

@property (assign, nonatomic) Class cellClass;

@property (assign, nonatomic) Class headerViewClass;

@property (strong, nonatomic) UITableView *tableView;

@property (strong, nonatomic) UICollectionView *collectionView;

@property (nonatomic, strong) LBFacCollectionViewFlowLayout *layout;

@property (copy, nonatomic) LBCustomCollectionCellSizeBlock customCellSize;

@property (nonatomic, copy) LBFacListViewSectionViewModel headerViewModel;

@property (nonatomic, assign) NSInteger maxShowOneLine;

@property (nonatomic, copy) LBFacBaseViewButtonClick headerViewClick;

@end

@implementation LBFacListView

#pragma mark - publice

- (instancetype)initTableViewWithFrame:(CGRect)frame
                              cellName:(NSString *)name
                             cellClick:(LBFacListViewCellClick)cellClick
                            otherClick:(LBFacListViewOtherClick)cellViewClick
{
    if (self = [super initWithFrame:frame]) {
        self.viewType = LBFacListViewTypeTableView;
        self.cellClass = NSClassFromString(name);;
        self.cellClick = cellClick;
        self.otherClick = cellViewClick;
        self.isOneSection = YES;
        [self createAllView];
    }
    return self;
}

- (instancetype)initCollectionViewWithFrame:(CGRect)frame
                                   cellName:(NSString *)name
                            maxItemsOneLine:(NSInteger)num
                                      click:(LBFacListViewCellClick)cellClick
                                 otherClick:(LBFacListViewOtherClick)cellViewClick
{
    if (self = [super initWithFrame:frame]) {
        self.viewType = LBFacListViewTypeCollectionView;
        self.cellClass = NSClassFromString(name);
        self.cellClick = cellClick;
        self.otherClick = cellViewClick;
        self.maxShowOneLine = num;
        self.isOneSection = YES;
        [self createAllView];
    }
    return self;
}

- (instancetype)initCollectionViewWithFlowLayout:(LBFacCollectionViewFlowLayout *)customFlowLayout
                                           frame:(CGRect)frame
                                        cellName:(NSString *)name
                                 maxItemsOneLine:(NSInteger)num
                                           click:(LBFacListViewCellClick)cellClick
                                      otherClick:(LBFacListViewOtherClick)cellViewClick
{
    if (self = [super initWithFrame:frame]) {
        self.viewType = LBFacListViewTypeCollectionView;
        self.cellClass = NSClassFromString(name);
        self.cellClick = cellClick;
        self.otherClick = cellViewClick;
        self.maxShowOneLine = num;
        self.isOneSection = YES;
        if (customFlowLayout) {
            self.layout = customFlowLayout;
            [self baseSettingUpForLayout:self.layout];
        }
        [self createAllView];
    }
    return self;
}

- (instancetype)registerHeaderViewClass:(Class)viewClass
                       HeaderModelBlock:(LBFacListViewSectionViewModel)modelBlock
{
    self.headerViewClass = viewClass;
    self.headerViewModel = modelBlock;
    
    if (LBFacListViewTypeCollectionView == self.viewType) {
        if ([self.cellClass fac_isNibView]) {
            [self.collectionView registerNib:[UINib nibWithNibName:NSStringFromClass(viewClass) bundle:nil] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:LBReuseHeaderSectionIdentifier];
        } else {
            [self.collectionView registerClass:viewClass forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:LBReuseHeaderSectionIdentifier];
        }
    } else {
        if ([self.cellClass fac_isNibView]) {
            [self.tableView registerNib:[UINib nibWithNibName:NSStringFromClass(viewClass) bundle:nil] forHeaderFooterViewReuseIdentifier:LBReuseHeaderSectionIdentifier];
        } else {
            [self.tableView registerClass:viewClass forHeaderFooterViewReuseIdentifier:LBReuseHeaderSectionIdentifier];
        }
    }
    return self;
}

- (instancetype)registerHeaderViewClass:(Class)viewClass
                       HeaderModelBlock:(LBFacListViewSectionViewModel)modelBlock
                        HeaderViewClick:(LBFacBaseViewButtonClick)clickBlock
{
    [self registerHeaderViewClass:viewClass HeaderModelBlock:modelBlock];
    
    self.headerViewClick = clickBlock;
    
    return self;
}

- (instancetype)customCollectionCellWithSize:(LBCustomCollectionCellSizeBlock)customCellSize
{
    self.customCellSize = customCellSize;
    return self;
}

- (void)createAllView
{
    self.isCellHighlight = YES;
    
    UIView *showView = [self facViewByType:self.viewType];
    
    [self addSubview:showView];
    
    [showView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.edges.mas_equalTo(self);
    }];
}

#pragma mark - private

- (UIView *)facViewByType:(LBFacListViewType)viewType
{
    if (LBFacListViewTypeCollectionView == viewType) {
        return self.collectionView;
    } else {
        return self.tableView;
    }
}

- (id)cellByIndexPath:(NSIndexPath *)indexPath viewType:(LBFacListViewType)viewType
{
    if (LBFacListViewTypeCollectionView == viewType) {
        LBFacCollectionViewCell *oneCell = (LBFacCollectionViewCell *)[self.collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass(self.cellClass) forIndexPath:indexPath];
        return oneCell;
    } else {
        LBFacTableViewCell *oneCell = (LBFacTableViewCell *)[self.tableView dequeueReusableCellWithIdentifier:NSStringFromClass(self.cellClass) forIndexPath:indexPath];
        return oneCell;
    }
    
}

- (id)cellModelByIndexPath:(NSIndexPath *)indexPath
{
    id cellModel = nil;
    if (self.isOneSection) {
        if (indexPath.row < self.cellModelArray.count) {
            cellModel = self.cellModelArray[indexPath.row];
        }
    } else {
        cellModel = self.cellModelArray[indexPath.section][indexPath.row];
    }
    
    return cellModel;
}

- (NSInteger)sectionsForListView
{
    if (self.isOneSection) {
        return 1;
    }
    return self.cellModelArray.count;
}

- (NSInteger)rowForListViewBy:(NSInteger)section
{
    if (self.isOneSection) {
        return self.cellModelArray.count;
    }
    return [self.cellModelArray[section] count];
}

#pragma mark - public

- (void)reloadListView
{
    if (LBFacListViewTypeCollectionView == self.viewType) {
        [self.collectionView reloadData];
    } else {
        [self.tableView reloadData];
    }
}

#pragma mark - setter


#pragma mark - getter

- (UITableView *)tableView
{
    if (!_tableView) {
        _tableView = [[UITableView alloc]initWithFrame:self.bounds style:UITableViewStylePlain];
        _tableView.tableFooterView = [[UIView alloc]init];
        [_tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
        _tableView.delegate = self;
        _tableView.dataSource = self;
        _tableView.estimatedRowHeight = 60;
        if ([self.cellClass fac_isNibView]) {
            [_tableView registerNib:[UINib nibWithNibName:NSStringFromClass(self.cellClass) bundle:nil] forCellReuseIdentifier:NSStringFromClass(self.cellClass)];
        } else {
            [_tableView registerClass:self.cellClass forCellReuseIdentifier:NSStringFromClass(self.cellClass)];
        }
    }
    return _tableView;
}

-(UICollectionView *)collectionView{
    if (!_collectionView) {
        _collectionView = [[UICollectionView alloc]initWithFrame:self.bounds collectionViewLayout:self.layout];
        [_collectionView setDelegate:(id<UICollectionViewDelegate> _Nullable)self];
        [_collectionView setDataSource:(id<UICollectionViewDataSource> _Nullable)self];
        [_collectionView setBackgroundColor:[UIColor whiteColor]];
        if ([self.cellClass fac_isNibView]) {
            [_collectionView registerNib:[UINib nibWithNibName:NSStringFromClass(self.cellClass) bundle:nil] forCellWithReuseIdentifier:NSStringFromClass(self.cellClass)];
        } else {
            [_collectionView registerClass:self.cellClass forCellWithReuseIdentifier:NSStringFromClass(self.cellClass)];
        }
        if ([self.cellClass fac_isNibView]) {
            [self.collectionView registerNib:[UINib nibWithNibName:NSStringFromClass([LBFacCollectionReusableView class]) bundle:nil] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:LBReuseHeaderSectionIdentifier];
        } else {
            [self.collectionView registerClass:[LBFacCollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:LBReuseHeaderSectionIdentifier];
        }
        
        _collectionView.backgroundColor = [UIColor clearColor];
    }
    return _collectionView;
}

- (LBFacCollectionViewFlowLayout *)layout
{
    if (!_layout) {
        _layout=[[LBFacCollectionViewFlowLayout alloc] init];
        [self baseSettingUpForLayout:_layout];
    }
    return _layout;
}

- (void)baseSettingUpForLayout:(LBFacCollectionViewFlowLayout *)layout
{
    CGFloat showWidth = CGRectGetWidth(self.frame);
    CGFloat leftSpace = layout.sectionInset.left;
    CGFloat rightSpace = layout.sectionInset.right;
    CGFloat viewSpace = layout.minimumInteritemSpacing;
    CGFloat cellHeight = [self.cellClass fac_heightForViewByModel:nil];
    CGFloat defaultWidth = (showWidth - (self.maxShowOneLine - 1) * viewSpace - leftSpace - rightSpace) * 1.0 / self.maxShowOneLine;
    layout.itemSize = CGSizeMake(defaultWidth - 1,cellHeight);
    layout.fac_delegate = self;
}

#pragma mark - UITableViewDelegate, UITableViewDataSource

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return [self sectionsForListView];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [self rowForListViewBy:section];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    LBFacTableViewCell *oneCell = [self cellByIndexPath:indexPath viewType:self.viewType];
    
    [oneCell fac_updateUIViewByModel:[self cellModelByIndexPath:indexPath]];
    
    __weak __typeof(&*self)weakSelf = self;
    [oneCell setFac_clickBlock:^(NSInteger index) {
        if (weakSelf.otherClick) {
            weakSelf.otherClick(indexPath, index);
        }
    }];
    return oneCell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    CGFloat height = [self.cellClass fac_heightForViewByModel:[self cellModelByIndexPath:indexPath]];
    
    return height;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    
    if (self.cellClick) {
        self.cellClick(indexPath);
    }
}

- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath
{
    return self.isCellHighlight;
}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    if (self.headerViewClass && self.headerViewModel) {
        return [self.headerViewClass fac_heightForViewByModel:self.headerViewModel(section)];
    }
    return 0;
}

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    if (self.headerViewClass && self.headerViewModel) {
        LBFacTableViewHeaderFooterView *view = [tableView dequeueReusableHeaderFooterViewWithIdentifier:LBReuseHeaderSectionIdentifier];
        id model = nil;
        if (self.headerViewModel) {
            model = self.headerViewModel(section);
            [view setFac_clickBlock:self.headerViewClick];
        }
        [view fac_updateUIViewByModel:model];
        return view;
    }
    return nil;
}

#pragma mark - UICollectionViewDelegate

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
    
    return [self sectionsForListView];
    
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    
    return [self rowForListViewBy:section];
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
    
    LBFacCollectionViewCell *oneCell = [self cellByIndexPath:indexPath viewType:self.viewType];
    
    [oneCell fac_updateUIViewByModel:[self cellModelByIndexPath:indexPath]];
    
    __weak __typeof(&*self)weakSelf = self;
    [oneCell setFac_clickBlock:^(NSInteger index) {
        if (weakSelf.otherClick) {
            weakSelf.otherClick(indexPath, index);
        }
    }];
    
    return oneCell;
}

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
    if (self.customCellSize) {
        CGSize newSize = self.customCellSize(indexPath);
        if (newSize.width <= 0) {
            newSize = self.layout.itemSize;
        }
        return newSize;
    }
    return self.layout.itemSize;
}

-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
    if (self.cellClick) {
        self.cellClick(indexPath);
    }
}

//这个方法是返回 Header的大小 size
-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section
{
    CGFloat width = CGRectGetWidth(self.bounds);
    if (self.headerViewClass && self.headerViewModel) {
        CGFloat height = [self.headerViewClass fac_heightForViewByModel:self.headerViewModel(section)];
        return CGSizeMake(width,height);
    }
    return CGSizeZero;
}

//这个也是最重要的方法 获取Header的 方法。
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
    LBFacCollectionReusableView *view = (LBFacCollectionReusableView *)[collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:LBReuseHeaderSectionIdentifier forIndexPath:indexPath];
    if ([kind isEqualToString:UICollectionElementKindSectionHeader] && self.headerViewClass) {
        id model = nil;
        if (self.headerViewModel) {
            model = self.headerViewModel(indexPath.section);
            [view fac_updateUIViewByModel:model];
            [view setFac_clickBlock:self.headerViewClick];
        }
    }
    return view;
}

#pragma mark - UICollectionViewLayout minimumInteritemSpacing change

- (void)minimumInteritemSpacingByIsFixedSize:(BOOL)isFixed
{
    if (isFixed) {
        //固定大小
        self.layout.minimumInteritemSpacing = 10;
    } else {
        if (self.maxShowOneLine > 1) {
            CGFloat showWidth = CGRectGetWidth(self.frame);
            CGFloat leftSpace = self.layout.sectionInset.left;
            CGFloat rightSpace = self.layout.sectionInset.right;
            CGFloat viewSpace = (showWidth - self.maxShowOneLine  * self.layout.itemSize.width - leftSpace - rightSpace) * 1.0 / (self.maxShowOneLine - 1);
            self.layout.minimumInteritemSpacing = viewSpace;
        }
    }
}

@end

